home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Users Group Library 1996 July
/
C-C++ Users Group Library July 1996.iso
/
listings
/
v_08_10
/
8n10122a
< prev
next >
Wrap
Text File
|
1990-08-28
|
18KB
|
552 lines
#include <alloc.h>
#include <bios.h>
#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "csimint.h"
int start_kb_process(void(*task)(void),int stacksize)
{
int proc_id;
set_kb_process = 1;
proc_id = start_process(task,stacksize);
set_kb_process = 0;
return(proc_id);
}
int start_process(void(*task)(void),int stacksize)
{
char *stack;
struct _simprocessT *process;
int *off_seg=(int *)&stack;
unsigned int stackbytes;
int oldinit;
/* Check to see if tack handler has been installed*/
if(getvect(_INTRPT_)!=task_handler)
/* if it has not been installed, attempt to */
if(install_handler())
/* if it doesn't install, report error and exit */
{
printf("error installing task handler \n");
exit_processing(1);
}
if(stacksize > 0x0fdf)
/* Max stack size in paragraphs (SEGMENT counts)*/
{
printf("stack size error: proc id : %d",totalprocs);
exit_processing(2);
}
stackbytes = stacksize * 16;
/* Setup Process header and stack */
process =
(struct _simprocessT *)
calloc(sizeof(struct _simprocessT) + stackbytes,1);
/* make sure there was enough memory */
if(process==NULL)
return(2);
stack = (char *)(process+1);
/* 'Normalize' the bottom of stack pointer, that is
make sure the offset is less then 16, as would be
the case if the program where compiled in the huge
memory model */
if(off_seg[0]>16)
for(;off_seg[0]>16;off_seg[1]++,off_seg[0]-=16);
/* remember, the stack actually starts high and
builds its way down, so put the pointer at the top.*/
stack += stackbytes - 1;
/* finish setup of stack and base pointers */
process->reg_sp = FP_OFF(stack);
process->reg_ss = FP_SEG(stack);
process->reg_bp = FP_OFF(stack);
process->proc_id = totalprocs++;
process->init = 1;
/* Setup start jump */
process->reg_cs = FP_SEG(task);
process->reg_ip = FP_OFF(task);
/* link into current processes */
if(processlist==NULL)
{
processlist = process;
processlist->next = process;
processlist->prev = process;
}
else
{
process->prev = processlist;
process->next = processlist->next;
process->next->prev = process;
processlist->next = process;
processlist = process;
}
if(set_kb_process)
kbprocess = processlist;
/* make sure we can get back to where we were... */
glbl_ss = _SS;
glbl_sp = _SP;
glbl_bp = _BP;
oldinit = _sim_init_val;
/* tell the task handler what routine the process uses */
glbl_fc = task;
/* tell the task handler that this proc is initing */
_sim_init_val=1;
/* set up the new stak and base pointers and ... */
_SS = process->reg_ss;
_SP = process->reg_sp;
_BP = process->reg_bp;
/* have the task_handle do the rest */
geninterrupt(_INTRPT_);
_SS = glbl_ss;
_SP = glbl_sp;
_BP = glbl_bp;
glbl_fc = NULL;
_sim_init_val = oldinit;
processlist = processlist->prev;
return(0);
}
void stop_process(int process_id)
{
struct _simprocessT *process;
int go;
go = 1;
process = processlist;
while(go)
{
if(process_id == process->proc_id)
{
process->status.kill_flag = 1;
process->start_time = _sim_system_time;
go = 0;
}
if(process->next == processlist)
{
if(go)
printf("\nattempted to stop non-existant proc\n");
go = 0;
}
else
{
process = process->next;
}
}
}
void sim_start(void)
{
_sim_init_val=0;
_last_update_time = *systimer;
geninterrupt(_INTRPT_);
}
void exit_processing(int condition)
{
struct _simprocessT *pholder;
setvect(_INTRPT_,old_vector);
printf("Exit processing, code : %d\n",condition);
processlist->prev->next = NULL;
do
{
pholder = processlist;
processlist = processlist->next;
free(pholder);
} while(processlist!=NULL);
exit(condition);
}
int install_handler(void)
{
void *new_vector;
_sim_init_val=2;
old_vector = getvect(_INTRPT_);
setvect(_INTRPT_,task_handler);
new_vector = getvect(_INTRPT_);
if(new_vector==old_vector)
return(1);
return(0);
}
void interrupt task_handler( unsigned bp,unsigned di,unsigned si,
unsigned ds,unsigned es,unsigned dx,
unsigned cx,unsigned bx,unsigned ax,
unsigned ip,unsigned cs,unsigned flags)
{
int notfound;
struct _simprocessT *procpntr;
if(_sim_init_val==2)
/* if this ever happens, it means that the task handler
was installed before it should have been, so de-install
it and stop the program */
{
exit_processing(10);
}
if(_sim_init_val==0) /* sim_start has been run */
{
processlist->reg_bp = _BP;
processlist->reg_sp = _SP;
processlist->reg_ss = _SS;
if(processlist->status.kill_flag)
{
if(processlist == kbprocess)
/* You can,t kill the kbproc */
processlist->status.kill_flag = 0;
else
{
if(processlist->next == processlist)
/* no more procs */
exit_processing(20);
/* break list */
processlist->prev->next = processlist->next;
/* move in front of break */
processlist = processlist->prev;
/* free dead proc */
free(processlist->next->prev);
/* fix break */
processlist->next->prev = processlist;
}
}
if((kbprocess!= NULL)&&(bioskey(1)))
processlist = kbprocess;
else
{
if(_sim_time_ratio != 0.0)
{
for(notfound = 1;notfound;)
{
if((kbprocess != NULL)&&(bioskey(1)))
{
processlist = kbprocess;
notfound = 0;
}
else
{
processlist = processlist->next;
if((*systimer - _last_update_time)>